package me.flyray.admin.biz;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import me.flyray.admin.constant.AdminCommonConstant;
import me.flyray.common.context.BaseContextHandler;
import me.flyray.common.exception.BusinessException;
import me.flyray.common.util.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.RequestBody;

import me.flyray.admin.entity.Dept;
import me.flyray.admin.entity.ResourceAuthority;
import me.flyray.admin.entity.Role;
import me.flyray.admin.entity.User;
import me.flyray.admin.entity.UserRole;
import me.flyray.admin.mapper.DeptMapper;
import me.flyray.admin.mapper.ResourceAuthorityMapper;
import me.flyray.admin.mapper.RoleMapper;
import me.flyray.admin.mapper.UserMapper;
import me.flyray.admin.mapper.UserRoleMapper;
import me.flyray.auth.common.config.UserAuthConfig;
import me.flyray.auth.common.util.jwt.IJWTInfo;
import me.flyray.auth.common.util.jwt.JWTHelper;
import me.flyray.common.constant.UserConstant;
import me.flyray.common.enums.UserType;
import me.flyray.common.msg.ResponseCode;
import me.flyray.common.util.EntityUtils;
import me.flyray.common.util.MD5;

import lombok.extern.slf4j.Slf4j;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class CommonBiz {
	
    @Autowired
    private UserAuthConfig userAuthConfig;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private ResourceAuthorityMapper resourceAuthorityMapper;
    @Value("${toplevel.dept.id}")
	private Integer toplevelDeptId;
    @Value("${admin.password}")
    private String defaultPassword;
    @Value("${admin.platformAuthorityId}")
    private Integer platformAuthorityId;
    @Value("${admin.merchantAuthorityId}")
    private Integer merchantAuthorityId;

	/**
	 * 1、添加一个组织结构（dept）
	 * 2、给部门下添加角色
	 * 2、添加一个用户，指定添加的默认角色
	 * @param param
	 * @return
	 */
	public Map<String, Object> addPlatformOrMerchant(@RequestBody Map<String, Object> param){
		Map<String, Object> result = new HashMap<String, Object>();
		String platformName = (String) param.get("platformName");
		String platformLoginName = (String) param.get("platformLoginName");
		String merchantName = (String) param.get("merchantName");
		String platformId = (String) param.get("platformId");
		String merchantId = (String) param.get("merchantId");
		Integer type = (Integer) param.get("userType");
		String mobilePhone = (String) param.get("mobilePhone");
		//用户信息获取
		String userNo = BaseContextHandler.getXId();
		String userName = BaseContextHandler.getXName();
		//dept表添加
		Map<String, Object> deptMap = new HashMap<String, Object>();
		deptMap.put("platformId", platformId);
		//如果是平台，平台的父级固定是顶级，id为1，如果修改了最高级目录则要修改修改此处值
		Integer parentId = toplevelDeptId;
		//如果不是平台管理员，则该部门一定存在，根据平台编号获取父机构编号
		if(!UserType.PLATFORM_ADMIN.getCode().equals(type)){
			Map<String, Object> deptPMap = new HashMap<String, Object>();
			deptPMap.put("parentId", parentId);
			deptPMap.put("platformId",platformId);
			Dept dept = EntityUtils.map2Bean(deptPMap, Dept.class);
			Dept deptOther = deptMapper.selectOne(dept);
			if(deptOther == null){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				throw new BusinessException(ResponseCode.DEPT_NO_EXIST);
			}
			parentId = deptOther.getId();

		}
		deptMap.put("parentId", parentId);
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			deptMap.put("name", platformName);
		}else if(UserType.MERCHANT_ADMIN.getCode().equals(type)){
			deptMap.put("name", merchantName);
		}
		deptMap.put("delFlag", "0");
		Dept dept = EntityUtils.map2Bean(deptMap, Dept.class);
		//1、添加部门
		String deptId = String.valueOf(SnowFlake.getId());
		dept.setDeptId(deptId);
		deptMapper.insert(dept);
		Dept deptOther = deptMapper.selectOne(dept);
		if(deptOther == null){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			throw new BusinessException(ResponseCode.DEPT_NO_EXIST);
		}
		//1、给部门下添加角色
		Map<String, Object> roleMap = new HashMap<String, Object>();
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			roleMap.put("roleName", platformName + "平台管理员");
		}else {
			roleMap.put("roleName", merchantName + "商户管理员");
		}

		roleMap.put("remark", "创建平台自动生成角色");
		roleMap.put("platformId", platformId);
		roleMap.put("isDelete", 1);
		Role role = EntityUtils.map2Bean(roleMap, Role.class);
		role.setCreateTime(new Date());
		//1、给部门下添加角色
		String roleId = String.valueOf(SnowFlake.getId());
		role.setRoleId(roleId);
		role.setDeptId(deptId);
		roleMapper.insertSelective(role);
		//添加用户
		Map<String, Object> userMap = new HashMap<String, Object>();
		userMap.put("userId", SnowFlake.getId());
		userMap.put("crtUser", userNo);
		userMap.put("crtName", userName);
		userMap.put("updUser", userNo);
		userMap.put("updName", userName);
		userMap.put("mobilePhone", mobilePhone);
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			userMap.put("username", platformLoginName);
		}else {
			userMap.put("username", merchantName);
		}
		//默认密码123456
		userMap.put("password", defaultPassword);
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			userMap.put("name", platformName);
		}else {
			userMap.put("name", merchantName);
		}
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			userMap.put("deptName", platformName);
		}else {
			userMap.put("deptName", merchantName);
		}
		userMap.put("description", "添加平台自动添加的平台管理员");
		//userMap.put("crtTime", new Date());
		if(UserType.MERCHANT_ADMIN.getCode().equals(type)){
			userMap.put("merchantId", merchantId);
		}
		userMap.put("platformId", platformId);
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			userMap.put("userType", UserType.PLATFORM_ADMIN.getCode());
		}else {
			userMap.put("userType", UserType.MERCHANT_ADMIN.getCode());
		}
		String crtUser = (String) param.get("crtUser");
		String crtName = (String) param.get("crtName");
		User entity = EntityUtils.map2Bean(userMap, User.class);
		entity.setDeptId(deptId);
		String md5pwd = MD5.md5(MD5.md5(entity.getPassword()) + UserConstant.PW_MD5_SALT);
		String md5Password = DigestUtils.md5DigestAsHex((DigestUtils.md5DigestAsHex(md5pwd.getBytes())+UserConstant.PW_MD5_SALT).getBytes());
		String password = new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(md5Password);
		entity.setPassword(password);
		entity.setCrtTime(new Date());
		entity.setUpdTime(new Date());
		entity.setCrtName(crtName);
		entity.setCrtUser(crtUser);
		entity.setUpdName(crtName);
		entity.setUpdUser(crtUser);
		//3、添加用户
		userMapper.addUser(entity);
		String userId = entity.getUserId();
		//添加关系
		UserRole userRole = new UserRole();
		userRole.setUserId(userId);
		userRole.setRoleId(roleId);
		userRoleMapper.insert(userRole);
		//资源
		Map<String, Object> resourceAuthorityMap = new HashMap<String, Object>();
		resourceAuthorityMap.put("roleId", roleId);
		if(UserType.PLATFORM_ADMIN.getCode().equals(type)){
			resourceAuthorityMap.put("authority", platformAuthorityId);
		}else {
			resourceAuthorityMap.put("authority", merchantAuthorityId);
		}
		try{
			//为角色赋予权限
			this.copyResourceAuthority(resourceAuthorityMap);
		} catch (Exception e) {
			e.printStackTrace();
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			throw new BusinessException(ResponseCode.SERVICE_NOT_AVALIABLE);
		}
		result.put("code", ResponseCode.OK.getCode());
		result.put("message", ResponseCode.OK.getMessage());
		return result;
	}
    
    public Map<String, Object> deletePlatformOrMerchant(Map<String, Object> param){
		log.info("【删除平台或商户下附加信息】   请求参数：{}",param);
    	Map<String, Object> respMap = new HashMap<String, Object>();
		String platformId = (String) param.get("platformId");
		String merchantId = (String) param.get("merchantId");
		String merchantName = (String) param.get("merchantName");
		String platformName = (String) param.get("platformName");
		Integer type = (Integer) param.get("type");
		
		///机构//////////////////////////////////////////////////////////////////////////////////////////////
		Dept dept = new Dept();
		dept.setPlatformId(platformId);
		if(UserType.PLATFORM_ADMIN.getCode() == type){
			dept.setName(platformName);
		}else if(UserType.MERCHANT_ADMIN.getCode() == type){
			dept.setName(merchantName);
		}
		dept.setDelFlag((byte) 0);
		Dept deptOther = deptMapper.selectOne(dept);
		String deptId = deptOther.getDeptId();

		///用户//////////////////////////////////////////////////////////////////////////////////////////////
		User entity = new User();
		entity.setPlatformId(platformId);
		if(UserType.MERCHANT_ADMIN.getCode() == type){
			entity.setMerchantId(merchantId);
		}
		List<User> users = userMapper.select(entity);
		for (int i = 0; i < users.size(); i++) {
			User user = users.get(i);
			
			///用户角色关系//////////////////////////////////////////////////////////////////////////////////////////////
			UserRole userRoleReq = new UserRole();
			userRoleReq.setUserId(user.getUserId());
			List<UserRole> userRoles = userRoleMapper.select(userRoleReq);
			for (int j = 0; j < userRoles.size(); j++) {
				UserRole userRole = userRoles.get(j);
				userRoleMapper.deleteByPrimaryKey(userRole.getId());
			}
			userMapper.deleteByPrimaryKey(user.getId());
		}
		
		deleteChildDept(deptId);
		
		respMap.put("code", ResponseCode.OK.getCode());
		respMap.put("message", ResponseCode.OK.getMessage());
		
		return respMap;
    }
    
    public void deleteChildDept(String deptId){
    	Dept deptReq = new Dept();
    	deptReq.setParentId(deptId);
		List<Dept> depts = deptMapper.select(deptReq);
		for (int i = 0; i < depts.size(); i++) {
			Dept dept = depts.get(i);
			Role roleReq = new Role();
			roleReq.setDeptId(dept.getDeptId());
			List<Role> roles = roleMapper.select(roleReq);
			for (int j = 0; j < roles.size(); j++) {
				Role role = roles.get(j);
				///角色资源//////////////////////////////////////////////////////////////////////////////////////////////
				ResourceAuthority authority = new ResourceAuthority();
		        authority.setAuthorityId(role.getRoleId() + "");
		        List<ResourceAuthority> authoritys = resourceAuthorityMapper.select(authority);
				for (int k = 0; k < authoritys.size(); k++) {
					ResourceAuthority resourceAuthority = authoritys.get(k);
					resourceAuthorityMapper.deleteByPrimaryKey(resourceAuthority.getId());
				}
				roleMapper.deleteByPrimaryKey(role.getRoleId());
			}
			deleteChildDept(dept.getDeptId());
			deptMapper.deleteByPrimaryKey(dept.getId());
		}
		Role roleReq = new Role();
		roleReq.setDeptId(deptId);
		List<Role> roles = roleMapper.select(roleReq);
		for (int j = 0; j < roles.size(); j++) {
			Role role = roles.get(j);
			///角色资源//////////////////////////////////////////////////////////////////////////////////////////////
			ResourceAuthority authority = new ResourceAuthority();
	        authority.setAuthorityId(role.getRoleId() + "");
	        List<ResourceAuthority> authoritys = resourceAuthorityMapper.select(authority);
			for (int k = 0; k < authoritys.size(); k++) {
				ResourceAuthority resourceAuthority = authoritys.get(k);
				resourceAuthorityMapper.deleteByPrimaryKey(resourceAuthority.getId());
			}
			roleMapper.deleteByPrimaryKey(role.getRoleId());
		}
		deptMapper.deleteByPrimaryKey(deptId);
    }
    
	public Map<String, Object> copyResourceAuthority(Map<String, Object> param) throws Exception{
		Map<String, Object> result = new HashMap<String, Object>();
		Long roleId = (Long) param.get("roleId");
		Integer authorityId = (Integer) param.get("authority");
		Example example = new Example(ResourceAuthority.class);
        Criteria criteria = example.createCriteria();
        //方法中固定使用id为13（name“云支付平台管理员（本角色绝对不能删除）”）的角色作为基础角色,如果基础角色修改了，则此处修改
        criteria.andEqualTo("authorityId", authorityId);
        criteria.andEqualTo("resourceType", "menu");
        List<ResourceAuthority> list = resourceAuthorityMapper.selectByExample(example);
        for (ResourceAuthority resourceAuthority : list) {
        	ResourceAuthority authority = new ResourceAuthority(AdminCommonConstant.AUTHORITY_TYPE_GROUP, AdminCommonConstant.RESOURCE_TYPE_MENU);
            authority.setAuthorityId(roleId + "");
            authority.setResourceId(resourceAuthority.getResourceId());
            //默认-1
            authority.setParentId("-1");
            resourceAuthorityMapper.insertSelective(authority);
		}
        //插入资源
        Example example2 = new Example(ResourceAuthority.class);
        Criteria criteria2 = example2.createCriteria();
        //方法中固定使用id为13（name“云支付平台管理员（本角色绝对不能删除）”）的角色作为基础角色,如果基础角色修改了，则此处修改
        criteria2.andEqualTo("authorityId", authorityId);
        criteria2.andEqualTo("resourceType", "button");
        List<ResourceAuthority> listBtn = resourceAuthorityMapper.selectByExample(example2);
        for (ResourceAuthority resourceAuthority : listBtn) {
        	ResourceAuthority authority = new ResourceAuthority(AdminCommonConstant.AUTHORITY_TYPE_GROUP, AdminCommonConstant.RESOURCE_TYPE_BTN);
            authority.setAuthorityId(roleId + "");
            authority.setResourceId(resourceAuthority.getResourceId());
            //默认-1
            authority.setParentId("-1");
            resourceAuthorityMapper.insertSelective(authority);
		}
    	result.put("code", ResponseCode.OK.getCode());
    	result.put("message", ResponseCode.OK.getMessage());
    	result.put("success", true);
    	return result;
	}
}
